package com.bysc.commonutils.utils;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Date;

/**
 * JWT工具类，用于生成JWT令牌、验证JWT令牌和从JWT令牌中提取信息。
 */
public class JwtUtils {
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";
    /**
     * 生成JWT令牌
     * @param id 用户ID
     * @param nickname 用户昵称
     * @return 生成的JWT令牌
     */
    public static String getJwtToken(String id, String nickname, String clubId) {
        // 设置JWT令牌过期时间为当前时间后7天
        Date expiredTime = new Date(LocalDate.now(ZoneOffset.UTC).plusDays(7).atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
        String JwtToken = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject("bysc-user")
                .setIssuedAt(new Date())
                .claim("id", id)
                .claim("nickname", nickname)
                .claim("clubId", clubId)
                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .setExpiration(expiredTime)
                .compact();

        return JwtToken;
    }


    /**
     * 验证JWT令牌是否有效
     * @param jwtToken 待验证的JWT令牌
     * @return true 如果JWT令牌有效，否则 false
     */
    public static boolean checkToken(String jwtToken) {
        if (jwtToken == null || "".equals(jwtToken)) return false;
        try {
            // 验证JWT签名是否有效，验证过期时间
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
    }

    /**
     * 从HttpServletRequest中获取JWT令牌，并提取其中的会员ID
     * @param request HTTP请求对象
     * @return JWT令牌中的会员ID，如果令牌不存在或无效，则返回空字符串
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
        if (request == null) return "";
        String jwtToken = request.getHeader("token");
        if (jwtToken == null || "".equals(jwtToken)) return "";
        try {
            // 解析JWT令牌，并提取其中的Claims信息
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();
            return (String) claims.get("id");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    public static String getClubIdByJwtToken(HttpServletRequest request) {
        if (request == null) return "";
        String jwtToken = request.getHeader("token");
        if (jwtToken == null || "".equals(jwtToken)) return "";
        try {
            // 解析JWT令牌，并提取其中的Claims信息
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();
            return (String) claims.get("clubId");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    public static String getMemberIdByJwtToken(String token) {
        String jwtToken = token;
        if (jwtToken == null || "".equals(jwtToken)) return "";
        try {
            // 解析JWT令牌，并提取其中的Claims信息
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();
            return (String) claims.get("id");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    public static String getNicknameByJwtToken(String token) {
        String jwtToken = token;
        if (StringUtils.isEmpty(jwtToken)) return "";
        try {
            // 解析JWT令牌，并提取其中的Claims信息
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();
            return (String) claims.get("nickname");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
